
#include<bits/stdc++.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<string.h>
#include<fcntl.h>

using namespace std;
#define N 2
//child
// void Write(int fd)
// {
//    string s = "hello,I am a child";
//    pid_t self = getpid();
//    int numb = 0;

//    char buff[1024];
//    int cnt = 5;
//    while(--cnt)
//    {
//      //构建
//      //buff[0] = 0;//字符串清空,只是为了提醒
//       //snprintf(buff,sizeof(buff),"%s-%d-%d\n",s.c_str(),self,numb++);
//       sprintf(buff,"%s-%d-%d\n",s.c_str(),self,numb++);
//     //   cout << buff;
//     //   sleep(1);

//       //写入父进程
//       write(fd,buff,strlen(buff));// + 1???
//       sleep(1);
//    }
//    //exit(0);
// }
// //father
// void Read(int fd)
// {   
//    char buff[1024];
//    int cnt = 5;
//    while(--cnt )
//    {
//     sleep(1);
//    }
//    while(1)
//    {
//  ssize_t n = read(fd,buff,sizeof(buff));//sizeof != strlen
//   if(n > 0)
//   {
//      buff[n] = '\0';
//   }
//    if(n > 0)
//     {
//         cout << "father get a message [" << getpid() << "]#" << buff;
//         sleep(4);
//     }
//    cout << "n : " << n << endl;
//    //sleep(1);
//    }
// }
void Write(int fd)
{
   string s = "hello,I am a child";
   pid_t self = getpid();
   int numb = 0;

   char buff[1024];
   while(1)
   {
    sleep(1);
     //构建
     //buff[0] = 0;//字符串清空,只是为了提醒
      //snprintf(buff,sizeof(buff),"%s-%d-%d\n",s.c_str(),self,numb++);
      sprintf(buff,"%s-%d-%d\n",s.c_str(),self,numb++);
    //   cout << buff;
    //   sleep(1);

      //写入父进程
      write(fd,buff,strlen(buff));// + 1???
    //   sleep(1);
   }
   //exit(0);
}
//father
void Read(int fd)
{   
   char buff[1024];
   int cnt = 0;
   while(1)
   {
    ++cnt;
 ssize_t n = read(fd,buff,sizeof(buff));//sizeof != strlen
   if(n > 0)
   {
      buff[n] = '\0';
      cout << "father get a message [" << getpid() << "]#" << buff;

   }
   else if(n == 0)
   {
    printf("father read file done!\n");
    break;
   }
   else break;
  // cout << "n : " << n << endl;
   //sleep(1);
   if(cnt > 5) break;
   }
}
int main()
{
  int pipefd[N] = {0};
  int n = pipe(pipefd);
  //创建管道
  if(n < 0) return 1;

  
//   printf("pipefd[0]:%d, pipefd[1]:%d\n",pipefd[0],pipefd[1]);
   pid_t id = fork();
   if(id < 0) return 2;
   if(id == 0)
   {
     //子 -- 写入 父进程--读取
     //单向 --需要关闭
     close(pipefd[0]);
     //IPC code
     Write(pipefd[1]);
     close(pipefd[1]);
     exit(0);
   }
   close(pipefd[1]);
  //IPC 代码
   Read(pipefd[0]);//读取5s
   close(pipefd[0]);
   cout << "father close fd" << pipefd[0] << endl;
   sleep(5);

   int status = 0;
   pid_t rid = waitpid(id,&status,0);
   if(rid < 0) return 3;
                                                               //没啥意义,不关心异常的退出码
   cout << "wait child success: " << rid << " exit code: " << ((status>>8)&(0xFF)) << " exit signal: " << (status& 0x7f) << endl;
  //WIFEXITED判断是否正常退出,若是为真
  //WEXITSTATUS若非0,提取退出码
   //低7位信号,一位dump ,次低八位,退出码
   sleep(5);
   cout << "father quit" << endl;
    //close(pipefd[0]);
  return 0;
}
